﻿Public Class UICommandBox

    Public Enum UICommandMessageType
        Normal
        [Error]
        Debug
    End Enum

    Public UserInterface As UserInterface 
    Public UICommands As UICommands

    Public Const MaxLineCount As Integer = 10
    Public Const MaxCommandHistory As Integer = 32
    Public Const Cursor As String = "_"
    Public Const DefaultPrompt As String = ">"
    Public Font As SpriteFont
    Public Background As Texture2D
    Public Prompt As String
    Public CommandLine As String = ""
    Public CursorIndex As Integer = 0
    Public Lines As New Queue(Of String)()
    Public CommandHistory As New List(Of String)()
    Public CommandHistoryIndex As Integer
    Public HasFocus As Boolean = False

    Public Sub New(ByRef UserInterface As UserInterface)
        Me.UserInterface = UserInterface
        UICommands = UserInterface.UICommands
        Font = UserInterface.TextureManager.GetTexture("Default").Font
        Background = UserInterface.TextureManager.GetTexture("Default").Texture2D
        Prompt = DefaultPrompt
    End Sub

    Public Sub CleanupQueue()
        While Lines.Count >= MaxLineCount
            Lines.Dequeue()
        End While
    End Sub

    Public Sub Echo(Text As String, Optional MessageType As UICommandMessageType = UICommandMessageType.Normal)
        Select Case MessageType
            Case UICommandMessageType.Normal
                Lines.Enqueue(Text)
            Case UICommandMessageType.Error
                Lines.Enqueue("ERROR: " & Text)
            Case UICommandMessageType.Debug
                Lines.Enqueue("DEBUG: " & Text)
        End Select
        CleanupQueue()
    End Sub

    Public Sub ExecuteCommand(Command As String) 'Todo: Determine message type, format string appropriatly
        Dim SpaceChars As Char() = New Char() {" "c}
        Lines.Enqueue(Prompt & Command)
        Command = Command.TrimStart(SpaceChars)
        Dim Args As New List(Of String)(Command.Split(SpaceChars))
        Dim CmdText As String = Args(0)
        Args.RemoveAt(0)
        Dim Cmd As UICommands.CommandInfo
        If UICommands.CommandTable.TryGetValue(CmdText.ToLower(), Cmd) Then
            Try
                Cmd.Callback(Command, Args)
            Catch e As Exception
                Lines.Enqueue("Unhandled Exception occurred!")
                Dim ErrorLines As String() = e.Message.Split(New Char() {ControlChars.Lf})
                For Each Line As String In ErrorLines
                    Lines.Enqueue(Line)
                Next
            End Try
        Else
            Lines.Enqueue("Unknown Command: " & Command)
        End If
        CleanupQueue()
        CommandHistory.Add(Command)
        While CommandHistory.Count > MaxCommandHistory ' Cleanup
            CommandHistory.RemoveAt(0)
        End While
        CommandHistoryIndex = CommandHistory.Count
        HasFocus = False
    End Sub

    Public Sub Draw(SpriteBatch As SpriteBatch)
        Dim Rect As New Rectangle()
        Rect.X = CInt(UserInterface.Width * 0.25F) '* 0.25F = Left Margin
        Rect.Y = CInt(UserInterface.Height * 0.65F) '* 0.6F  = Top Margin
        Rect.Width = CInt(UserInterface.Width * 0.5F)
        Rect.Height = CInt(MaxLineCount * Font.LineSpacing)
        SpriteBatch.Draw(Background, Rect, New Color(0, 0, 0, 200))
        Dim Pos As New Vector2(Rect.X, Rect.Y)
        For Each line As String In Lines
            SpriteBatch.DrawString(Font, line, Pos, Color.White)
            Pos.Y += Font.LineSpacing
        Next
        Dim LeftPart As String = Prompt + CommandLine.Substring(0, CursorIndex)
        Dim CursorPos As Vector2 = Pos + Font.MeasureString(LeftPart)
        CursorPos.Y = Pos.Y
        SpriteBatch.DrawString(Font, [String].Format("{0}{1}", Prompt, CommandLine), Pos, Color.White)
        SpriteBatch.DrawString(Font, Cursor, CursorPos, Color.White)
    End Sub
End Class